package com.lz.code.mongodb.controller;

import com.lz.code.mongodb.model.Consultant;
import com.lz.code.mongodb.vo.req.ConsultantReq;
import com.mongodb.client.result.DeleteResult;
import com.mongodb.client.result.UpdateResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.regex.Pattern;

/**
 * @author: LiuZhi
 * @date: 2022/4/8 20:44
 * @description:
 */
@RestController
@RequestMapping("/consultant")
@Slf4j
public class ConsultantController {

    private final MongoTemplate mongoTemplate;

    public ConsultantController(MongoTemplate mongoTemplate) {
        this.mongoTemplate = mongoTemplate;
    }

    /**
     * 基础查询
     *
     * @param req
     * @return
     */
    @PostMapping("/search")
    public List<Consultant> search(@RequestBody ConsultantReq req) {
        Assert.notNull(req, "查询参数不能为空");
        // 1. 分页 Page 查询
        Pageable pageable = PageRequest.of(req.getPageNum() - 1, req.getPageSize(), Sort.by(Sort.Order.desc("serviceMemberCount")));
        Query query = new Query().with(pageable);
        // 2. 按照姓名模糊查询
        if (StringUtils.isNotBlank(req.getName())) {
            Pattern compile = Pattern.compile("^.*" + req.getName() + ".*$", Pattern.CASE_INSENSITIVE);
            query.addCriteria(Criteria.where("name").regex(compile));
        }
        // 3. 按照性别等值查询 FEMALE MALE
        if (StringUtils.isNotBlank(req.getGender())) {
            query.addCriteria(Criteria.where("gender").is(req.getGender()));
        }
        // 4. 按照姓名查询多个
        if (!CollectionUtils.isEmpty(req.getNames())) {
            query.addCriteria(Criteria.where("name").in(req.getNames()));
            // 5. 查询数量
            log.info(String.format("count:%s", mongoTemplate.count(query, Consultant.class)));
        }
        return mongoTemplate.find(query, Consultant.class);
    }

    /**
     * 查询所有
     *
     * @return
     */
    @PostMapping("/find-all")
    public List<Consultant> findAll() {
        // 6. 查询所有
        return mongoTemplate.findAll(Consultant.class);
    }

    /**
     * 新增
     * 1. save() 已弃用
     * 2. insert() 如果主键存在, 会抛出 DuplicateKeyException
     *
     * @param consultant
     */
    @PostMapping("/save")
    public void save(@RequestBody Consultant consultant) {
        Assert.notNull(consultant, "保存参数不能为空");
        Consultant insert = mongoTemplate.insert(consultant);
        log.info(String.format("insert:%s", insert));
    }


    /**
     * 更新
     * 1. updateFirst() 更新一条数据
     * 2. updateMulti() 更新多条数据
     * 3. upsert() 更新数据, 如果数据不存在就新增
     * @param id
     * @param name
     */
    @GetMapping("/update")
    public void update(@RequestParam("id") String id, @RequestParam("name") String name) {
        Query query = Query.query(Criteria.where("_id").is(id));
        Update update = Update.update("name", name);
        UpdateResult updateResult = mongoTemplate.updateFirst(query, update, Consultant.class);
        log.info(String.format("update:%s", updateResult));
    }

    /**
     * 删除
     */
    @GetMapping("/delete")
    public void delete() {
        Query query = Query.query(Criteria.where("name").is("测试"));
        DeleteResult deleteResult = mongoTemplate.remove(query,Consultant.class);
        log.info(String.format("delete:%s", deleteResult));
    }

}
